#ifndef SENSORTRAYMATERIALDATA_H
#define SENSORTRAYMATERIALDATA_H

#include "configManager/configobject.h"
#include "enumhelper.h"
#include "materialdata.h"

class SensorTrayMaterialData : public MaterialData
{
    Q_PROPERTY(int materialState READ materialState WRITE setMaterialState NOTIFY materialStateChanged)
    Q_PROPERTY(double dispPrPosX READ dispPrPosX WRITE setDispPrPosX NOTIFY dispPrPosXChanged)
    Q_PROPERTY(double dispPrPosY READ dispPrPosY WRITE setDispPrPosY NOTIFY dispPrPosYChanged)
    Q_PROPERTY(double dispPrOffsetOriginX READ dispPrOffsetOriginX WRITE setDispPrOffsetOriginX NOTIFY
                   dispPrOffsetOriginXChanged)
    Q_PROPERTY(double dispPrOffsetOriginY READ dispPrOffsetOriginY WRITE setDispPrOffsetOriginY NOTIFY
                   dispPrOffsetOriginYChanged)
    Q_PROPERTY(double dispPrOffsetT READ dispPrOffsetT WRITE setDispPrOffsetT NOTIFY dispPrOffsetTChanged)
    Q_PROPERTY(int willBeHandledByWhichDH READ willBeHandledByWhichDH WRITE setWillBeHandledByWhichDH NOTIFY
                   willBeHandledByWhichDHChanged)
    Q_PROPERTY(int shotGlueOrder READ shotGlueOrder WRITE setShotGlueOrder NOTIFY shotGlueOrderChanged)

    Q_OBJECT
public:
    enum MaterialState
    {
        Init,
        DispPrOk,
        DispPrNg,
        DispenseOk,
        DispenseNg,
        DispCheckOk,
        DispCheckNg,
        BondPrOk,
        BondPrNg,
        Bonded,
        Cured,
        PostBondPrNg,
        PostBondOk,
        PostBondNg
    };
    Q_ENUM(MaterialState)

    enum DispenseHead
    {
        None,
        Left,
        Right
    };

    enum ShotGlueOrder
    {
        UpToDown,
        DownToUp
    };

    static EnumHelper<MaterialState> &MaterialStateEnumInfo()
    {
        static EnumHelper<MaterialState> instance(staticMetaObject, "MaterialState");
        return instance;
    }

    Q_INVOKABLE SensorTrayMaterialData(QObject *parent = nullptr) : MaterialData(parent)
    {
        init();
    }

    int materialState() const
    {
        return m_materialState;
    }

    double dispPrOffsetT() const
    {
        return m_dispPrOffsetT;
    }

    double dispPrOffsetOriginX() const
    {
        return m_dispPrOffsetOriginX;
    }

    double dispPrOffsetOriginY() const
    {
        return m_dispPrOffsetOriginY;
    }

    int willBeHandledByWhichDH() const
    {
        return m_willBeHandledByWhichDH;
    }

    int shotGlueOrder() const
    {
        return m_shotGlueOrder;
    }

    double dispPrPosX() const
    {
        return m_dispPrPosX;
    }

    double dispPrPosY() const
    {
        return m_dispPrPosY;
    }

    // MaterialData interface
public:
    virtual void reset(int materialState) override
    {
        setMaterialState(materialState);
        setDispPrOffsetT(0);
        setDispPrOffsetOriginX(0);
        setDispPrOffsetOriginY(0);
        setWillBeHandledByWhichDH(0);
        setShotGlueOrder(0);
        setDispPrPosX(0);
        setDispPrPosY(0);
    }
    virtual QString getMaterialState() override
    {
        return MaterialStateEnumInfo().enumToName(static_cast<MaterialState>(m_materialState));
    }

public slots:
    void setMaterialState(int materialState)
    {
        if (m_materialState == materialState)
            return;

        m_materialState = materialState;
        emit materialStateChanged(m_materialState);
        emit stateChanged(rowIndex(), columnIndex());
    }

    void setDispPrOffsetT(double dispPrOffsetT)
    {
        //        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_dispPrOffsetT, dispPrOffsetT))
            return;

        m_dispPrOffsetT = dispPrOffsetT;
        emit dispPrOffsetTChanged(m_dispPrOffsetT);
    }

    void setDispPrOffsetOriginX(double dispPrOffsetOriginX)
    {
        //        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_dispPrOffsetOriginX, dispPrOffsetOriginX))
            return;

        m_dispPrOffsetOriginX = dispPrOffsetOriginX;
        emit dispPrOffsetOriginXChanged(m_dispPrOffsetOriginX);
    }

    void setDispPrOffsetOriginY(double dispPrOffsetOriginY)
    {
        //        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_dispPrOffsetOriginY, dispPrOffsetOriginY))
            return;

        m_dispPrOffsetOriginY = dispPrOffsetOriginY;
        emit dispPrOffsetOriginYChanged(m_dispPrOffsetOriginY);
    }

    void setWillBeHandledByWhichDH(int willBeHandledByWhichDH)
    {
        if (m_willBeHandledByWhichDH == willBeHandledByWhichDH)
            return;

        m_willBeHandledByWhichDH = willBeHandledByWhichDH;
        emit willBeHandledByWhichDHChanged(m_willBeHandledByWhichDH);
    }

    void setShotGlueOrder(int shotGlueOrder)
    {
        if (m_shotGlueOrder == shotGlueOrder)
            return;

        m_shotGlueOrder = shotGlueOrder;
        emit shotGlueOrderChanged(m_shotGlueOrder);
    }

    void setDispPrPosX(double dispPrPosX)
    {
        //        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_dispPrPosX, dispPrPosX))
            return;

        m_dispPrPosX = dispPrPosX;
        emit dispPrPosXChanged(m_dispPrPosX);
    }

    void setDispPrPosY(double dispPrPosY)
    {
        //        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_dispPrPosY, dispPrPosY))
            return;

        m_dispPrPosY = dispPrPosY;
        emit dispPrPosYChanged(m_dispPrPosY);
    }

signals:
    void materialStateChanged(int materialState);

    void dispPrOffsetTChanged(double dispPrOffsetT);

    void dispPrOffsetOriginXChanged(double dispPrOffsetOriginX);

    void dispPrOffsetOriginYChanged(double dispPrOffsetOriginY);

    void willBeHandledByWhichDHChanged(int willBeHandledByWhichDH);

    void shotGlueOrderChanged(int shotGlueOrder);

    void dispPrPosXChanged(double dispPrPosX);

    void dispPrPosYChanged(double dispPrPosY);

private:
    int m_materialState = 0;
    double m_dispPrOffsetT = 0;
    double m_dispPrOffsetOriginX = 0;
    double m_dispPrOffsetOriginY = 0;
    int m_willBeHandledByWhichDH = 0;
    int m_shotGlueOrder = 0;
    double m_dispPrPosX = 0;
    double m_dispPrPosY = 0;
};

#endif    // SENSORTRAYMATERIALDATA_H
